package sessions;

import java.sql.Date;
import java.util.LinkedList;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import entities.Admin;
import entities.Skill;
import entities.SkillRequest;
import entities.Status;
import entities.User;
import exceptions.DuplicatedSkillException;
import exceptions.SkillRequestException;

/**
 * Session Bean implementation class SkillManager
 */
@Stateless
public class SkillManager implements SkillManagerRemote, SkillManagerLocal {

	@PersistenceContext(unitName = "SWIMv2")
	private EntityManager em;

	/**
	 * Default constructor.
	 */
	public SkillManager() {
		// TODO Auto-generated constructor stub
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see sessions.SkillManagerRemote#request(entities.User, entities.Admin,
	 * java.lang.String)
	 */
	@Override
	public void request(User fromUser, Admin toAdmin, String message)
			throws SkillRequestException {
		List<SkillRequest> result = new LinkedList<SkillRequest>();
		Status status = Status.PENDING;
		Query q = em
				.createQuery("FROM SkillRequest sr WHERE sr.fromUser=:fromUser AND sr.toAdmin=:toAdmin AND sr.status=:status");
		q.setParameter("fromUser", fromUser);
		q.setParameter("toAdmin", toAdmin);
		q.setParameter("status", status);
		List<?> res = q.getResultList();
		for (Object obj : res) {
			result.add((SkillRequest) obj);
		}
		if (result.isEmpty()) {
			SkillRequest sr = new SkillRequest();
			sr.setFrom(fromUser);
			sr.setTo(toAdmin);
			sr.setMessage(message);
			sr.setDate(new Date(System.currentTimeMillis()));
			sr.setStatus(Status.PENDING);
			em.persist(sr);
			// em.flush();
			return;
		}
		throw new SkillRequestException();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see sessions.SkillManagerRemote#fetchIncoming(entities.Admin)
	 */
	@Override
	public List<SkillRequest> fetchIncoming(String username) {
		List<SkillRequest> result = new LinkedList<SkillRequest>();
		Query q = em
				.createQuery("FROM SkillRequest sr WHERE sr.toAdmin.username=:username");
		q.setParameter("username", username);
		List<?> res = q.getResultList();
		for (Object obj : res) {
			result.add((SkillRequest) obj);
		}
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see sessions.SkillManagerRemote#fetchOutgoing(entities.User)
	 */
	@Override
	public List<SkillRequest> fetchOutgoing(String username) {
		List<SkillRequest> result = new LinkedList<SkillRequest>();
		Query q = em
				.createQuery("FROM SkillRequest sr WHERE sr.fromUser.username=:username");
		q.setParameter("username", username);
		List<?> res = q.getResultList();
		for (Object obj : res) {
			result.add((SkillRequest) obj);
		}
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see sessions.SkillManagerRemote#fetch(int)
	 */
	public SkillRequest fetch(int id) {
		Query q = em.createQuery("FROM SkillRequest sr WHERE sr.id=:id");
		q.setParameter("id", id);
		SkillRequest sr = (SkillRequest) q.getSingleResult();
		return sr;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see sessions.SkillManagerRemote#accept(entities.SkillRequest)
	 */
	@Override
	public void accept(SkillRequest sr) {
		sr.accept();
		em.merge(sr);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see sessions.SkillManagerRemote#refuse(entities.SkillRequest)
	 */
	@Override
	public void refuse(SkillRequest sr) {
		sr.refuse();
		em.merge(sr);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see sessions.SkillManagerRemote#addSkill(java.lang.String)
	 */
	@Override
	public void addSkill(String name) throws DuplicatedSkillException {
		List<Skill> result = new LinkedList<Skill>();
		Query q = em.createQuery("FROM Skill s WHERE s.name=:name");
		q.setParameter("name", name);
		List<?> res = q.getResultList();
		for (Object obj : res) {
			result.add((Skill) obj);
		}
		if (result.isEmpty()) {
			Skill skill = new Skill();
			skill.setName(name);
			em.persist(skill);
			// em.flush();
			return;
		}
		throw new DuplicatedSkillException();
	}
	
	public Skill fetchSkill(int id){
		Query q = em.createQuery("FROM Skill s WHERE s.id=:id");
		q.setParameter("id", id);
		Skill s = (Skill) q.getSingleResult();
		return s;
	}
	
	public List<Skill> fetchAllSkills(){
		List<Skill> result = new LinkedList<Skill>();
		Query q = em.createQuery("FROM Skill s");
		List<?> res = q.getResultList();
		for (Object obj : res) {
			result.add((Skill) obj);
		}
		return result;
	}

}
